home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Applications
/
Python 1.3.3
/
Python 133 SRC
/
Extensions
/
img
/
imgsgimodule.c
< prev
next >
Wrap
Text File
|
1996-01-15
|
25KB
|
1,065 lines
/***********************************************************
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
******************************************************************/
/* rgb objects */
#include "Python.h"
#include "import.h"
static PyObject *format_rgb, *format_rgb_b2t, *format_rgb_choices;
static PyObject *format_grey, *format_grey_b2t, *format_xgrey,
*format_xgrey_b2t, *format_grey_choices;
static PyObject *format_rgb8, *format_rgb8_b2t, *format_xrgb8,
*format_xrgb8_b2t, *format_rgb8_choices;
static PyObject *format_choices;
#define is_4bytefmt(fmt) (fmt==format_rgb||fmt==format_rgb_b2t)
#define is_alignfmt(fmt) (fmt==format_grey||fmt==format_grey_b2t||\
fmt==format_rgb8||fmt==format_rgb8_b2t)
#define is_b2tfmt(fmt) (fmt==format_grey_b2t||fmt==format_xgrey_b2t||\
fmt==format_rgb8_b2t||fmt==format_xrgb8_b2t||\
fmt==format_rgb_b2t)
#define is_ditherfmt(fmt) (fmt==format_rgb8||fmt==format_rgb8_b2t||\
fmt==format_xrgb8||fmt==format_xrgb8_b2t)
#define is_greyfmt(fmt) (fmt==format_grey||fmt==format_grey_b2t||\
fmt==format_xgrey||fmt==format_xgrey_b2t)
typedef struct {
PyObject_HEAD
PyObject *dict; /* Attributes dictionary */
int is_reader; /* TRUE if this is a reader */
char *filename; /* filename of the image file */
FILE *filep;
int width, height;
int nchannels;
int rle;
int colormapID;
} rgbobject;
static PyObject *errobject;
staticforward PyTypeObject Rgbtype;
#define is_rgbobject(v) ((v)->ob_type == &Rgbtype)
static char doc_rgb[] =
"This object can be used to read/write RGB image files.\n"
"The 'width', 'height' and 'format' attributes give info about the\n"
"image data read (or to be written)";
/* Routine to easily obtain C data from the dict python data */
int
rgbselfattr(self, name, fmt, ptr, wanterr)
rgbobject *self;
char *name;
char *fmt;
void *ptr;
int wanterr;
{
PyObject *obj;
char errbuf[100];
obj = PyDict_GetItemString(self->dict, name);
if (obj == NULL) {
if (wanterr) {
sprintf(errbuf, "Required attribute '%s' not set", name);
PyErr_SetString(errobject, errbuf);
return 0;
} else {
PyErr_Clear();
return 0;
}
}
if (!PyArg_Parse(obj, fmt, ptr)) {
if (!wanterr)
PyErr_Clear();
return 0;
}
return 1;
}
/* Routine to easily insert integer into dictionary */
rgbsetintattr(self, name, value)
rgbobject *self;
char *name;
int value;
{
PyObject *obj;
int rv;
obj = PyInt_FromLong(value);
rv = PyDict_SetItemString(self->dict, name, obj);
Py_DECREF(obj);
return rv;
}
static rgbobject *
newrgbobject()
{
rgbobject *xp;
xp = PyObject_NEW(rgbobject, &Rgbtype);
if (xp == NULL)
return NULL;
xp->dict = PyDict_New();
xp->filename = NULL;
xp->filep = NULL;
return xp;
}
static int
RGBreadheader(self)
rgbobject *self;
{
unsigned char header[512];
int dimension;
/*
The RGB header looks as follows:
2 bytes IRIS image file magic number
1 byte storage format
1 byte number of bytes per pixel channel
2 bytes number of dimensions
2 bytes x size in pixels
2 bytes y size in pixels
2 bytes number of channels
4 bytes minimum pixel value
4 bytes maximum pixel value
4 bytes ignored
80 bytes image name
4 bytes colormap ID
404 bytes ignored
*/
if (fread(header, 1, 512, self->filep) != 512) {
PyErr_SetString(errobject, "Truncated RGB file");
return 0;
}
if ((header[0]<<8|header[1]) != 474) {
PyErr_SetString(errobject, "Not an RGB file");
return 0;
}
self->rle = header[2];
if (self->rle != 0 && self->rle != 1)
goto BadRGB;
if (header[3] != 1) /* only support 1 byte per pixel */
goto BadRGB;
dimension = header[4]<<8|header[5];
if (dimension < 1 || dimension > 3)
goto BadRGB;
self->width = header[6]<<8|header[7];
self->height = header[8]<<8|header[9];
rgbsetintattr(self, "width", self->width);
rgbsetintattr(self, "height", self->height);
self->nchannels = header[10]<<8|header[11];
if (self->nchannels != 1 && self->nchannels != 3 && self->nchannels != 4)
goto BadRGB;
if (dimension == 1) {
if (self->height != 1 || self->nchannels != 1)
goto BadRGB;
} else if (dimension == 2) {
if (self->nchannels != 1)
goto BadRGB;
}
/*
self->pinmin = header[12]<<24|header[13]<<16|header[14]<<8|header[15];
self->pinmax = header[16]<<24|header[17]<<16|header[18]<<8|header[19];
*/
if (header[20]) {
PyObject *obj;
int rv;
header[99] = 0; /* just to be sure... */
obj = PyString_FromString((char *)header+20);
rv = PyDict_SetItemString(self->dict, "name", obj);
Py_XDECREF(obj);
}
self->colormapID = header[104]<<24|header[105]<<16|
header[106]<<8|header[107];
if (self->colormapID == 1) {
if (self->nchannels != 1)
goto BadRGB;
PyDict_SetItemString(self->dict, "format", format_rgb8);
PyDict_SetItemString(self->dict, "format_choices",
format_rgb8_choices);
return 1;
} else if (self->colormapID != 0)
goto BadRGB;
if (self->nchannels == 1) {
PyDict_SetItemString(self->dict, "format", format_grey);
PyDict_SetItemString(self->dict, "format_choices",
format_grey_choices);
} else {
PyDict_SetItemString(self->dict, "format", format_rgb);
PyDict_SetItemString(self->dict, "format_choices",
format_rgb_choices);
}
return 1;
BadRGB:
PyErr_SetString(errobject, "Illegal or unsupported RGB file");
return 0;
}
static int
initrgbreader(self, name)
rgbobject *self;
char *name;
{
char *name_copy;
if ((name_copy = malloc(strlen(name)+1)) == NULL) {
PyErr_NoMemory();
return 0;
}
strcpy(name_copy, name);
self->filename = name_copy;
self->is_reader = 1;
self->filep = fopen(name, "rb");
if (self->filep == NULL) {
PyErr_SetFromErrno(PyExc_IOError);
return 0;
}
if (!RGBreadheader(self))
return 0;
if (PyErr_Occurred())
return 0;
return 1;
}
static int
initrgbwriter(self, name)
rgbobject *self;
char *name;
{
char *name_copy;
if ((name_copy = malloc(strlen(name)+1)) == NULL) {
PyErr_NoMemory();
return 0;
}
strcpy(name_copy, name);
self->filename = name_copy;
self->is_reader = 0;
PyDict_SetItemString(self->dict, "format", format_rgb);
PyDict_SetItemString(self->dict, "format_choices", format_choices);
if (PyErr_Occurred())
return 0;
return 1;
}
/* rgb methods */
static void
rgb_dealloc(xp)
rgbobject *xp;
{
Py_XDECREF(xp->dict);
if (xp->filename)
free(xp->filename);
if (xp->filep)
fclose(xp->filep);
PyMem_DEL(xp);
}
static PyObject *
RGBreadimage(self, fmt)
rgbobject *self;
PyObject *fmt;
{
int x, y, z;
int v;
PyObject *rv;
char *ptr;
int xstride, ystride, zstride;
x = self->width;
y = self->height;
z = self->nchannels;
if (z == 1) {
if (is_alignfmt(fmt))
x = (x + 3) & ~3;
rv = PyString_FromStringAndSize(NULL, x * y);
if (rv == NULL)
return NULL;
ptr = PyString_AS_STRING((PyStringObject *) rv);
memset(ptr, 0, x * y);
if (is_b2tfmt(fmt)) {
ystride = x;
} else {
ptr += x * (y - 1);
ystride = -x;
}
ystride -= self->width;
zstride = 0;
xstride = 1;
} else {
rv = PyString_FromStringAndSize(NULL, x * y * 4);
if (rv == NULL)
return NULL;
ptr = PyString_AS_STRING((PyStringObject *) rv);
memset(ptr, 0, x * y * 4);
if (is_b2tfmt(fmt)) {
ystride = x * 4;
} else {
ptr += x * (y - 1) * 4;
ystride = -x * 4;
}
ptr += 3;
zstride = -ystride * y - 1;
ystride -= x * 4;
xstride = 4;
}
for (z = self->nchannels; z > 0; z--) {
for (y = self->height; y > 0; y--) {
for (x = self->width; x > 0; x--) {
v = getc(self->filep);
if (v == EOF) {
PyErr_SetString(errobject,
"Truncated RGB file");
Py_DECREF(rv);
return NULL;
}
*ptr = v;
ptr += xstride;
}
ptr += ystride;
}
ptr += zstride;
}
return rv;
}
static int
readtab(filep, tab, len)
FILE *filep;
unsigned long *tab;
int len;
{
int ch;
unsigned long v;
int i;
while (--len >= 0) {
v = 0;
for (i = 4; i > 0; i--) {
if ((ch = getc(filep)) == EOF) {
PyErr_SetString(errobject,
"Truncated RGB file");
return 0;
}
v = v << 8 | ch;
}
*tab++ = v;
}
return 1;
}
static int
writetab(filep, tab, len)
FILE *filep;
unsigned long *tab;
int len;
{
int ch;
unsigned long v;
int i;
while (--len >= 0) {
v = *tab++;
for (i = 4; i > 0; i--) {
putc(v >> 24, filep);
v <<= 8;
}
}
if (ferror(filep))
return 0;
return 1;
}
static int
compare(p1, p2)
const void *p1, *p2;
{
return ** (const unsigned long **) p1 - ** (const unsigned long **) p2;
}
static PyObject *
RGBreadrleimage(self, fmt)
rgbobject *self;
PyObject *fmt;
{
int tablen = self->height * self->nchannels;
unsigned long *starttab = malloc(tablen * sizeof(unsigned long));
unsigned long *lengthtab = malloc(tablen * sizeof(unsigned long));
unsigned long **sorttab = malloc(tablen * sizeof(unsigned long *));
unsigned long **sorttab_ptr;
unsigned long seek_ptr, seek_pos;
int i, prev_row;
int width, n, y, z, stride;
PyObject *rv;
unsigned char *ptr, *optr, *cptr;
int reverse;
if (starttab == NULL || lengthtab == NULL || sorttab == NULL) {
PyErr_NoMemory();
goto ErrorExit;
}
if (!readtab(self->filep, starttab, tablen))
goto ErrorExit;
if (!readtab(self->filep, lengthtab, tablen))
goto ErrorExit;
for (i = 0; i < tablen; i++)
sorttab[i] = &starttab[i];
qsort(sorttab, tablen, sizeof(unsigned long *), compare);
sorttab_ptr = sorttab;
width = self->width;
if (self->nchannels == 1) {
if (is_alignfmt(fmt))
width = (width + 3) & ~3;
stride = 1;
} else {
stride = 4;
width *= 4;
}
if (!is_b2tfmt(fmt)) {
/* If height > 1, the following is still != 0, and it
is very handy to have this number floating around
when we have to reverse the image. If height == 0
or 1 it doesn't matter whether we reverse or not */
reverse = width * (self->height - 1);
} else
reverse = 0;
rv = PyString_FromStringAndSize(NULL, width * self->height);
if (rv == NULL)
goto ErrorExit;
ptr = (unsigned char *)PyString_AS_STRING((PyStringObject *) rv);
memset(ptr, 0, width * self->height);
prev_row = -1;
seek_pos = 512 + 2 * tablen * 4;
while (--tablen >= 0) {
i = *sorttab_ptr++ - starttab;
seek_ptr = starttab[i];
if (seek_ptr == prev_row) {
/* copy a row */
if (reverse) {
cptr = ptr + reverse - y * width;
optr = ptr + reverse - (i%self->height)*width;
} else {
cptr = ptr + y * width;
optr = ptr + (i % self->height) * width;
}
cptr += stride - z - 1;
optr += stride - (i / self->height) - 1;
n = self->width;
while (--n >= 0) {
*optr = *cptr;
optr += stride;
cptr += stride;
}
continue;
}
if (seek_pos != seek_ptr) {
while (seek_pos < seek_ptr) {
if ((n = getc(self->filep)) == EOF)
goto EOFError;
seek_pos++;
}
if (seek_pos > seek_ptr) {
PyErr_SetString(errobject, "Bad rle table");
goto ErrorExit;
}
}
z = i / self->height;
y = i % self->height;
if (reverse)
optr = ptr + reverse - y * width;
else
optr = ptr + y * width;
optr += stride - z - 1;
for (;;) {
int pixel, count;
if ((pixel = getc(self->filep)) == EOF)
goto EOFError;
seek_pos++;
if (!(count = (pixel & 0x7f)))
break;
if (pixel & 0x80) {
while (count--) {
if ((pixel = getc(self->filep)) == EOF)
goto EOFError;
seek_pos++;
*optr = pixel;
optr += stride;
}
} else {
if ((pixel = getc(self->filep)) == EOF)
goto EOFError;
seek_pos++;
while (count--) {
*optr = pixel;
optr += stride;
}
}
}
prev_row = seek_ptr;
}
free(starttab);
free(lengthtab);
free(sorttab);
return rv;
EOFError:
PyErr_SetString(errobject, "Truncated RGB file");
ErrorExit:
if (starttab)
free(starttab);
if (lengthtab)
free(lengthtab);
if (sorttab)
free(sorttab);
return NULL;
}
static char doc_read[] = "Read the actual image data as a string.";
static PyObject *
rgb_read(self, args)
rgbobject *self;
PyObject *args;
{
PyObject *fmt;
if (!PyArg_ParseTuple(args,""))
return NULL;
if (!self->is_reader) {
PyErr_SetString(errobject, "Cannot read() from writer object");
return NULL;
}
/* Get format (and other args), check, read data, return it */
if (!rgbselfattr(self, "format", "O", &fmt, 1))
return NULL;
if (self->nchannels == 1) {
if (self->colormapID == 0) {
if (!is_greyfmt(fmt))
goto illegal_format;
} else {
/* self->colormapID == 1 */
if (!is_ditherfmt(fmt))
goto illegal_format;
}
} else {
if (!is_4bytefmt(fmt))
goto illegal_format;
}
if (self->rle)
return RGBreadrleimage(self, fmt);
else
return RGBreadimage(self, fmt);
illegal_format:
PyErr_SetString(errobject, "Illegal format");
return NULL;
}
#define putbyte(p,x) ((p)[0]=(x))
#define putshort(p,x) ((p)[0]=(x)>>8,(p)[1]=(x))
#define putlong(p,x) ((p)[0]=(x)>>24,(p)[1]=(x)>>16,(p)[2]=(x)>>8,(p)[3]=(x))
static int
RGBwriteheader(self, fmt)
rgbobject *self;
PyObject *fmt;
{
char *name;
char header[512];
memset(header, 0, 512);
putshort(header+0, 474);
putbyte(header+2, self->rle);
putbyte(header+3, 1);
if (self->nchannels == 1)
if (self->height == 1)
putshort(header+4, 1);
else
putshort(header+4, 2);
else
putshort(header+4, 3);
putshort(header+6, self->width);
putshort(header+8, self->height);
putshort(header+10, self->nchannels);
putlong(header+12, 0);
putlong(header+16, 255);
if (!rgbselfattr(self, "name", "s", &name, 0))
name = "no name";
strncpy(header+24, name, 79);
if (is_ditherfmt(fmt))
putlong(header+104, 1);
else
putlong(header+104, 0);
if (fwrite(header, 1, 512, self->filep) != 512) {
PyErr_SetFromErrno(PyExc_IOError);
return 0;
}
return 1;
}
static PyObject *
RGBwriteimage(self, fmt, ptr)
rgbobject *self;
PyObject *fmt;
unsigned char *ptr;
{
int x, y, z;
int v;
int xstride, ystride, zstride;
x = self->width;
y = self->height;
z = self->nchannels;
if (z == 1) {
if (is_alignfmt(fmt))
x = (x + 3) & ~3;
if (is_b2tfmt(fmt)) {
ystride = x;
} else {
ptr += x * (y - 1);
ystride = -x;
}
ystride -= self->width;
zstride = 0;
xstride = 1;
} else {
if (is_b2tfmt(fmt)) {
ystride = x * 4;
} else {
ptr += x * (y - 1) * 4;
ystride = -x * 4;
}
ptr += 3;
zstride = -ystride * y - 1;
ystride -= x * 4;
xstride = 4;
}
for (z = self->nchannels; z > 0; z--) {
for (y = self->height; y > 0; y--) {
for (x = self->width; x > 0; x--) {
putc(*ptr, self->filep);
ptr += xstride;
}
ptr += ystride;
}
ptr += zstride;
}
fflush(self->filep);
Py_INCREF(Py_None);
return Py_None;
}
static int
compressrow(iptr, rlebuf, length, stride)
unsigned char *iptr;
unsigned char *rlebuf;
int length, stride;
{
unsigned char *ibufend = iptr + length * stride;
unsigned char *optr = rlebuf;
unsigned char *sptr;
int stride2 = 2 * stride;
int count, todo, cc;
while (iptr < ibufend) {
sptr = iptr;
iptr += stride2;
while (iptr < ibufend && (iptr[-stride2] != iptr[-stride] ||
iptr[-stride] != iptr[0]))
iptr += stride;
iptr -= stride2;
count = (iptr - sptr) / stride;
while (count) {
todo = count > 126 ? 126 : count;
count -= todo;
*optr++ = 0x80 | todo;
while (--todo >= 0) {
*optr++ = *sptr;
sptr += stride;
}
}
sptr = iptr;
cc = *iptr;
iptr += stride;
while (iptr < ibufend && *iptr == cc)
iptr += stride;
count = (iptr - sptr) / stride;
while (count) {
todo = count > 126 ? 126 : count;
count -= todo;
*optr++ = todo;
*optr++ = cc;
}
}
*optr++ = 0;
return optr - rlebuf;
}
static PyObject *
RGBwriterleimage(self, fmt, ptr)
rgbobject *self;
PyObject *fmt;
unsigned char *ptr;
{
unsigned char *rlebuf;
unsigned long *starttab, *lengthtab;
long pos;
int tablen, rlebuflen, len;
int i, y, z;
int xsize, ysize, zsize, xstride, ystride;
xsize = ystride = self->width;
ysize = self->height;
zsize = self->nchannels;
tablen = ysize * zsize;
rlebuflen = 1.05 * xsize + 10;
starttab = (unsigned long *) malloc(tablen * sizeof(unsigned long));
lengthtab = (unsigned long *) malloc(tablen * sizeof(unsigned long));
rlebuf = (unsigned char *) malloc(rlebuflen);
if (starttab == NULL || lengthtab == NULL || rlebuf == NULL) {
PyErr_NoMemory();
goto ErrorExit;
}
if (zsize == 1) {
if (is_alignfmt(fmt))
ystride = (ystride + 3) & ~3;
xstride = 1;
} else {
xstride = 4;
ystride *= 4;
ptr += 3;
}
if (!is_b2tfmt(fmt)) {
ptr += ystride * (ysize - 1);
ystride = -ystride;
}
ystride += zsize;
pos = 512 + 2 * tablen * 4;
if (fseek(self->filep, pos, SEEK_SET))
goto WriteError;
i = 0;
for (y = ysize; y > 0; y--) {
for (z = zsize; z > 0; z--) {
len = compressrow(ptr, rlebuf, xsize, xstride);
if (len > rlebuflen) {
PyErr_SetString(errobject,
"rlebuf is too small - bad poop");
goto ErrorExit;
}
starttab[i] = pos;
lengthtab[i] = len;
if (fwrite(rlebuf, 1, len, self->filep) != len)
goto WriteError;
pos += len;
ptr--;
i += ysize;
}
ptr += ystride;
i += 1 - tablen;
}
if (fseek(self->filep, 512, SEEK_SET))
goto WriteError;
if (!writetab(self->filep, starttab, tablen))
goto WriteError;
if (!writetab(self->filep, lengthtab, tablen))
goto WriteError;
fseek(self->filep, 0, SEEK_END);
fflush(self->filep);
free(starttab);
free(lengthtab);
free(rlebuf);
Py_INCREF(Py_None);
return Py_None;
WriteError:
PyErr_SetString(errobject, "Error writing RGB file");
ErrorExit:
if (starttab)
free(starttab);
if (lengthtab)
free(lengthtab);
if (rlebuf)
free(rlebuf);
return NULL;
}
static char doc_write[] = "Write the image data.";
static PyObject *
rgb_write(self, args)
rgbobject *self;
PyObject *args;
{
unsigned char *data;
int datalen;
int i, width;
PyObject *fmt;
if (!PyArg_ParseTuple(args, "s#", &data, &datalen))
return NULL;
if (self->is_reader) {
PyErr_SetString(errobject, "Cannot write() to reader object");
return NULL;
}
if (!rgbselfattr(self, "width", "i", &self->width, 1) ||
!rgbselfattr(self, "height", "i", &self->height, 1) ||
!rgbselfattr(self, "format", "O", &fmt, 1))
return NULL;
if (is_4bytefmt(fmt)) {
if (!rgbselfattr(self, "rgba", "i", &i, 0))
i = 0;
if (i)
self->nchannels = 4;
else
self->nchannels = 3;
self->colormapID = 0;
i = 4;
} else {
self->nchannels = 1;
if (is_ditherfmt(fmt))
self->colormapID = 1;
else
self->colormapID = 0;
i = 1;
}
width = self->width;
if (is_alignfmt(fmt))
width = (width + 3) & ~3;
if (width * self->height * i != datalen) {
PyErr_SetString(errobject, "Incorrect datasize");
return NULL;
}
self->filep = fopen(self->filename, "wb");
if (self->filep == NULL) {
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
if (!rgbselfattr(self, "rle", "i", &self->rle, 0))
self->rle = 1;
if (!RGBwriteheader(self, fmt))
return NULL;
if (self->rle)
return RGBwriterleimage(self, fmt, data);
else
return RGBwriteimage(self, fmt, data);
}
static struct PyMethodDef rgb_methods[] = {
{"read", (PyCFunction)rgb_read, 1, doc_read},
{"write", (PyCFunction)rgb_write, 1, doc_write},
{NULL, NULL} /* sentinel */
};
static PyObject *
rgb_getattr(xp, name)
rgbobject *xp;
char *name;
{
PyObject *v;
if (xp->dict != NULL) {
if (strcmp(name, "__dict__") == 0) {
Py_INCREF(xp->dict);
return xp->dict;
}
if (strcmp(name, "__doc__") == 0) {
return PyString_FromString(doc_rgb);
}
v = PyDict_GetItemString(xp->dict, name);
if (v != NULL) {
Py_INCREF(v);
return v;
}
}
return Py_FindMethod(rgb_methods, (PyObject *)xp, name);
}
static int
rgb_setattr(xp, name, v)
rgbobject *xp;
char *name;
PyObject *v;
{
if (xp->dict == NULL) {
xp->dict = PyDict_New();
if (xp->dict == NULL)
return -1;
}
if (v == NULL) {
int rv = PyDict_DelItemString(xp->dict, name);
if (rv < 0)
PyErr_SetString(PyExc_AttributeError,
"delete non-existing imgrgb attribute");
return rv;
}
else
return PyDict_SetItemString(xp->dict, name, v);
}
static PyTypeObject Rgbtype = {
PyObject_HEAD_INIT(&PyType_Type)
0, /*ob_size*/
"imgrgb", /*tp_name*/
sizeof(rgbobject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)rgb_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)rgb_getattr, /*tp_getattr*/
(setattrfunc)rgb_setattr, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
};
static char doc_newreader[] = "Create reader for file passed as arg.";
static PyObject *
rgb_newreader(self, args)
PyObject *self;
PyObject *args;
{
char *filename;
rgbobject *obj;
if (!PyArg_ParseTuple(args, "s", &filename))
return NULL;
if ((obj = newrgbobject()) == NULL)
return NULL;
if (!initrgbreader(obj, filename)) {
rgb_dealloc(obj);
return NULL;
}
return (PyObject *)obj;
}
static char doc_newwriter[] = "Create writer for file passed as arg.";
static PyObject *
rgb_newwriter(self, args)
PyObject *self;
PyObject *args;
{
char *filename;
rgbobject *obj;
if (!PyArg_ParseTuple(args, "s", &filename))
return NULL;
if ((obj = newrgbobject()) == NULL)
return NULL;
if (!initrgbwriter(obj, filename)) {
rgb_dealloc(obj);
return NULL;
}
return (PyObject *)obj;
}
/* List of functions defined in the module */
static struct PyMethodDef rgb_module_methods[] = {
{"reader", rgb_newreader, 1, doc_newreader},
{"writer", rgb_newwriter, 1, doc_newwriter},
{NULL, NULL} /* sentinel */
};
/* Initialization function for the module (*must* be called initimgrgb) */
static char doc_imgrgb[] = "Module that reads and writes RGB image files.";
void
initimgsgi()
{
PyObject *m, *d, *x, *formatmodule, *formatdict;
/* Create the module and add the functions */
m = Py_InitModule("imgsgi", rgb_module_methods);
/* Add some symbolic constants to the module */
d = PyModule_GetDict(m);
errobject = PyString_FromString("imgsgi.error");
PyDict_SetItemString(d, "error", errobject);
x = PyString_FromString(doc_imgrgb);
PyDict_SetItemString(d, "__doc__", x);
/* Get supported formats */
if ((formatmodule = PyImport_ImportModule("imgformat")) == NULL)
Py_FatalError("imgsgi depends on imgformat");
if ((formatdict = PyModule_GetDict(formatmodule)) == NULL)
Py_FatalError("imgformat has no dict");
format_rgb = PyDict_GetItemString(formatdict,"rgb");
format_rgb_b2t = PyDict_GetItemString(formatdict,"rgb_b2t");
format_rgb_choices = Py_BuildValue("(OO)", format_rgb, format_rgb_b2t);
format_grey = PyDict_GetItemString(formatdict,"grey");
format_grey_b2t = PyDict_GetItemString(formatdict,"grey_b2t");
format_xgrey = PyDict_GetItemString(formatdict,"xgrey");
format_xgrey_b2t = PyDict_GetItemString(formatdict,"xgrey_b2t");
format_grey_choices = Py_BuildValue("(OOOO)",
format_grey, format_grey_b2t,
format_xgrey, format_xgrey_b2t);
format_rgb8 = PyDict_GetItemString(formatdict,"rgb8");
format_rgb8_b2t = PyDict_GetItemString(formatdict,"rgb8_b2t");
format_xrgb8 = PyDict_GetItemString(formatdict,"xrgb8");
format_xrgb8_b2t = PyDict_GetItemString(formatdict,"xrgb8_b2t");
format_rgb8_choices = Py_BuildValue("(OOOO)",
format_rgb8, format_rgb8_b2t,
format_xrgb8, format_xrgb8_b2t);
format_choices = Py_BuildValue("(OOOOOOOOOO)",
format_rgb, format_rgb_b2t,
format_grey, format_grey_b2t,
format_xgrey, format_xgrey_b2t,
format_rgb8, format_rgb8_b2t,
format_xrgb8, format_xrgb8_b2t);
/* Check for errors */
if (PyErr_Occurred())
Py_FatalError("can't initialize module imgsgi");
}